﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<string>

#include<algorithm>
#include"List.h"
#include"String.h"
using namespace std;


//包扩展，法1，编译时递归的逻辑展开
//void showlist()
//{
//	cout << endl;
//}
//
//template<class T,class... Args>
//void showlist(T&& x,Args&&...args)
//{
//	cout << x << ' ';
//	showlist(args...);
//}
//
//template<class... Args>
//void print(Args&&... args)
//{
//	showlist(args...);
//}

//包扩展，法2（了解），多次调用GetArg
//template <class T>
//const T& GetArg(const T& x)
//{
//	cout << x << " ";
//	return x;
//}
//
//template <class ...Args>
//void Arguments(Args... args)
//{}
//
//template <class ...Args>
//void Print(Args... args)
//{
//	// 注意GetArg必须返回或者到的对象，这样才能组成参数包给Arguments
//	Arguments(GetArg(args)...);
//}
//
//struct Student
//{
//	string name;
//	int age;
//	int height;
//};
//
//int main()
//{
//	//Print(1, 1.1, string("111"));
//	vector<Student> arr = { {"zhangsan",18,185},{"lisi",20,175},{"wangwu",35,180} };
//	sort(arr.begin(), arr.end(), [](Student s1, Student s2) {
//		return s1.age < s2.age; });
//	sort(arr.begin(), arr.end(), [](Student s1, Student s2) {
//		return s1.height < s2.height; });
//	return 0;
//}



////可变模板参数
////参数类型可变
////参数个数可变
////打印参数包内容
//template <class ...Args>
//void Print(Args... args)
//{
//	 cout << sizeof...(args) << endl;
//
//	 // 可变参数模板编译时解析
//	 // 下⾯是运⾏获取和解析，所以不⽀持这样⽤
//	 for (size_t i = 0; i < sizeof...(args); i++)
//	 {
//		cout << args[i] << " ";
//	 }
//	 cout << endl;
//}
//
//int main()
//{
//	Print();
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1, string("xxxxx"), 2.2);
//	return 0;
//}

//void ShowList()
//{
//	// 编译器时递归的终⽌条件，参数包是0个时，直接匹配这个函数
//	cout << endl;
//}
//
//template <class T, class ...Args>
//void ShowList(T x, Args... args)
//{
//	cout << x << " ";
//	// args是N个参数的参数包
//	// 调⽤ShowList，参数包的第⼀个传给x，剩下N-1传给第⼆个参数包
//	ShowList(args...);
//}
//
//// 编译时递归推导解析参数
//template <class ...Args>
//void Print(Args... args)
//{
//	ShowList(args...);
//}
//
//int main()
//{
//	Print();
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1, string("xxxxx"), 2.2);
//	return 0;
//}

//template <class T>
//const T& GetArg(const T& x)
//{
//	cout << x << " ";
//	return x;
//}
//template <class ...Args>
//void Arguments(Args... args)
//{}
//
//template <class ...Args>
//void Print(Args... args)
//{
//	// 注意GetArg必须返回获得到的对象，这样才能组成参数包给Arguments
//	Arguments(GetArg(args)...);
//}
//
//// 本质可以理解为编译器编译时，包的扩展模式
//// 将上⾯的函数模板扩展实例化为下⾯的函数
////void Print(int x, string y, double z)
////{
////	Arguments(GetArg(x), GetArg(y), GetArg(z));
////}
//
//int main()
//{
//	Print(1, string("xxxxx"), 2.2);
//	return 0;
//}


//int main()
//{
//	bao::list<bao::string> lt;
//	cout << endl;
//
//	// 传左值，跟push_back⼀样，⾛拷⻉构造
//	bao::string s1("111111111111");
//	lt.push_back(s1);
//	lt.emplace_back(s1);
//	cout<< endl;
//
//	// 右值，跟push_back⼀样，⾛移动构造
//	lt.push_back(move(s1));
//	lt.emplace_back(move(s1));
//	cout  << endl;
//
//	// 直接把构造string参数包往下传，直接⽤string参数包构造string
//	// 这⾥达到的效果是push_back做不到的
//	lt.emplace_back("111111111111");
//	lt.push_back("111111111111");
//	cout << endl<<endl;
//
//	bao::list<pair<bao::string, int>> lt1;
//	// 跟push_back⼀样
//	// 构造pair + 拷⻉/移动构造pair到list的节点中data上
//	pair<bao::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	cout << endl;
//	// 跟push_back⼀样
//	lt1.emplace_back(move(kv));
//	cout  << endl;
//
//	////////////////////////////////////////////////////////////////////
//	// 直接把构造pair参数包往下传，直接⽤pair参数包构造pair
//	// 这⾥达到的效果是push_back做不到的
//	lt1.emplace_back("苹果", 1);
//	lt1.push_back({ "苹果", 1 });
//	cout << endl;
//	return 0;
//}

//int main()
//{
//	// ⼀个简单的lambda表达式
//	auto add1 = [](int x, int y)->int {return x + y; };
//	cout << add1(1, 2) << endl;
//	// 1、捕捉为空也不能省略
//	// 2、参数为空可以省略
//	// 3、返回值可以省略，可以通过返回对象⾃动推导
//	// 4、函数题不能省略
//	auto func1 = []
//	{
//		cout << "hello bit" << endl;
//		
//	};
//	func1();
//	return 0;
//}

struct Goods
{
	string _name;  // 名字
	double _price; // 价格
	int _evaluate; // 评价
	// ...

	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

int main()
{
	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3}, { "菠萝", 1.5, 4 } };
	// 类似这样的场景，我们实现仿函数对象或者函数指针支持商品中
	// 不同项的比较，相对还是比较麻烦的，那么这里lambda就很好用了
	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
		return g1._price < g2._price; });

	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
		return g1._price > g2._price; });

	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
		return g1._evaluate < g2._evaluate; });

	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
		return g1._evaluate > g2._evaluate; });

	return 0;
}


